﻿
ierd_tgp.tpf_ui.Require("frame_bottom\\wg_frame_bottom\\node_tips.lua");

progress_node_tips_area = 
{
    inited_ = false;
    parent_id_ = 0;
    ctrl_id_to_item_ = {};
    game_id_ = 0;

    item_count_ = 0;
    index_to_percent_ = {};
    index_to_tips_ = {};

    cur_progress_ = 0;

    hinting_game_id_ = 0;
    ready_hinting_game_id_ = 0;
    hinting_count_ = 0;

    repo_extension_info = {};

    inner_log = function (msg, core_msg)
        base_utility.log(string.format("[progress_node_tips_area] %s", msg), core_msg);
    end;

    show_progress_node = function (parent_id, game_id)
        progress_node_tips_area.get_repo_extension_info(game_id);
        if game_id == progress_node_tips_area.game_id_ and 
           progress_node_tips_area.inited_ == true then
            -- 已经初始化过
            -- 若扩展包数量没变化，无需重新构造节点
            if progress_node_tips_area.is_repo_extension_count_change(game_id) == false then
                -- 检查比例是否有变化，若有则更新位置
                if progress_node_tips_area.is_repo_extension_ratio_change(game_id) == true then
                    progress_node_tips_area.inner_log("ratio change , refresh layout");
                    progress_node_tips_area.post_refresh_layout(game_id);
                end;
                return;
            end;
        end

        progress_node_tips_area.inited_ = false;

        local progress_bar_ctn_ptr = ui_utility.get_ctrl_ptr_by_id(parent_id);
        if progress_bar_ctn_ptr == nil then 
            return;
        end

        progress_node_tips_area.parent_id_ = parent_id;
        progress_node_tips_area.game_id_ = game_id;

        progress_node_tips_area.init_progress_node(game_id);
    end;

    get_repo_extension_info = function(game_id)
        progress_node_tips_area.repo_extension_info = 
            comm_center.call_service("i_service_tinysetup_repo_extension_info",
                                     {game_id = game_id});
    end;

    is_repo_extension_count_change = function(game_id)
        local extension_count = 0;
        local info = progress_node_tips_area.repo_extension_info;
        if info ~= nil and info.result == true and info.repo_pkgs ~= nil and 
           type(info.repo_pkgs) == "table" then
            extension_count = #(info.repo_pkgs) - 1;
        end;

        if progress_node_tips_area.item_count_ ~= extension_count then
            return true;
        else
            return false;
        end;
    end;

    is_repo_extension_ratio_change = function(game_id)
        local change = false;
        local info = progress_node_tips_area.repo_extension_info;
        if info == nil or info.result == false or info.repo_pkgs == nil or 
           type(info.repo_pkgs) ~= "table" then
            return change;
        end;
        
        local repo_pkgs_count = #(info.repo_pkgs);
        local percent = 0;
        for index, item_info in pairs(info.repo_pkgs) do
            if index == repo_pkgs_count then
                break;
            end;
            percent = percent + tonumber(item_info.ratio);
            if progress_node_tips_area.index_to_percent_[index] ~= nil and
               progress_node_tips_area.index_to_percent_[index] ~= percent then
                change = true;
                progress_node_tips_area.index_to_percent_[index] = percent;
            end;

            progress_node_tips_area.index_to_tips_[index]  = item_info.desc;
        end;

        if change then
            for ctrl_id, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
                local item_index = item:get_index();
                local percent = progress_node_tips_area.index_to_percent_[item_index];
                if percent ~= nil then
                    item:set_percent(percent * 100);
                end;
            end;
        end;

        for ctrl_id, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            local item_index = item:get_index();
            local desc = progress_node_tips_area.index_to_tips_[item_index];
            if desc ~= nil then
                item:set_tips(desc);
            end;
        end;

        return change;
    end;

    init_progress_node = function (game_id)
        local info = progress_node_tips_area.repo_extension_info;

        if info == nil or info.result == false or info.repo_pkgs == nil or 
           type(info.repo_pkgs) ~= "table" then
            return;
        end;

        -- 删除旧的控件
        for ctrl_id, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            item:delete();
        end;
        progress_node_tips_area.ctrl_id_to_item_ = {};
        progress_node_tips_area.item_count_ = 0;
        progress_node_tips_area.index_to_percent_ = {};
        progress_node_tips_area.index_to_tips_ = {};

        local repo_pkgs_count = #(info.repo_pkgs);
        local percent = 0;
        local has_error = false;
        for index, item_info in pairs(info.repo_pkgs) do
            if index == repo_pkgs_count then
                break;
            end;

            if tonumber(item_info.ratio) == 0.0 then
                has_error = true;
                break;
            end;

            local item_ctrl_id = layout_mgr.restore_sub_layout_multi(
                            progress_node_tips_area.parent_id_, "frame_bottom\\ProgressNode.tpf");
            percent = percent + tonumber(item_info.ratio);
            local item = node_tips:new(percent * 100, item_info.desc, item_ctrl_id, 
                                       game_id, index);

            if nil ~= item then
                progress_node_tips_area.ctrl_id_to_item_[item_ctrl_id] = item;
                progress_node_tips_area.item_count_ = progress_node_tips_area.item_count_ + 1;
                progress_node_tips_area.index_to_percent_[index] = percent;
                progress_node_tips_area.index_to_tips_[index] = item_info.desc;
            end
        end

        if has_error == true then
            -- 存在错误的比例信息，不展示节点信息
            progress_node_tips_area.hide_progress_node();
            return;
        end;

        -- 进行异步布局，解决父控件还没有布局完成的情况
        local param = {};
        param["game_id"] = game_id;
        local json = base_utility.table_to_json(param);
        event_center.post_event(frame_bottom_event.PROGRESS_NODE_LAYOUT_EVENT, json, true);

        progress_node_tips_area.inited_ = true;
    end;

    hide_progress_node = function()
        progress_node_tips_area.game_id_ = 0;
        -- 删除控件
        for ctrl_id, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            item:delete();
        end;

        progress_node_tips_area.ctrl_id_to_item_ = {};
        progress_node_tips_area.item_count_ = 0;
        progress_node_tips_area.index_to_percent_ = {};
        progress_node_tips_area.index_to_tips_ = {};
        progress_node_tips_area.inited_ = false;
    end;

    refresh_progress_node_status = function(game_id, progress)
        if game_id ~= progress_node_tips_area.game_id_ then
            return
        end
        progress_node_tips_area.cur_progress_ = progress;

        for key, icon_item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            if nil ~= icon_item then
                if tonumber(icon_item.percent_) < tonumber(progress) then
                    icon_item:refresh_state(node_tips.NODE_STATE.active);
                else
                    icon_item:refresh_state(node_tips.NODE_STATE.no_active);
                end
            end
        end
    end;


    do_layout = function()
        local progress_bar_ptr = ui_utility.get_ctrl_ptr_by_id(progress_node_tips_area.parent_id_);
        if nil == progress_bar_ptr then
            return;
        end
        
        -- 根据进度条的宽度来计算每个icon的偏移值
        local progress_bar_width = 0;
        local progress_bar_rc = progress_bar_ptr:GetRectEx(FALSE,TRUE);
        if progress_bar_rc ~= nil then
            progress_bar_width = progress_bar_rc.right - progress_bar_rc.left;
        end

        if progress_bar_width == 0 then 
            return;
        end

        for key, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            if nil ~= item then
                item:refresh_node_pos(progress_bar_width);
                item:show();
            end
        end
    end;

    get_progress_node_item = function(item_ctrl_id)
        local item = nil;
        for ctrl_id, val in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            if item_ctrl_id == ctrl_id then
                item = val;
                break;
            end
        end
        return item;
    end;

    on_progress_node_hover = function(game_id, percent, icon_offset)

    end;

    on_progress_node_leave = function()

    end;

    on_mainframe_position_change = function(game_id)
        if game_id ~= progress_node_tips_area.game_id_ then
            return;
        end
        progress_node_tips_area.do_layout();
    end;

    on_progress_bar_pos_change = function(game_id)
        if game_id ~= progress_node_tips_area.game_id_ then
            return;
        end
        progress_node_tips_area.post_refresh_layout(game_id);
    end;

    post_refresh_layout = function(game_id)
        local param = {};
        param["game_id"] = game_id;
        local json = base_utility.table_to_json(param);
        event_center.post_event(frame_bottom_event.PROGRESS_NODE_LAYOUT_EVENT, json, true);
    end;

    handle_progress_node_layout = function(event_id, json_str)
        local param = base_utility.json_to_table(json_str);
        if param == nil then
            base_utility.log("bad json param.");
            return;
        end
        if param.game_id ~= progress_node_tips_area.game_id_ then
            return;
        end
        progress_node_tips_area.do_layout();
    end;

    check_should_show_all_tips = function()
        if progress_node_tips_area.ready_hinting_game_id_ == 0 or 
           progress_node_tips_area.ready_hinting_game_id_ ~= progress_node_tips_area.game_id_ then
            return;
        end;
        if wg_frame_bottom_view.is_visible() == false then
            return;
        end;
        progress_node_tips_area.show_all_node_tips_first(
                                                progress_node_tips_area.ready_hinting_game_id_);
        progress_node_tips_area.ready_hinting_game_id_ = 0;
    end;

    show_all_node_tips_first = function(game_id)
        if progress_node_tips_area.hinting_game_id_ == game_id or game_id == 0 or
           progress_node_tips_area.game_id_ ~= game_id then
            return;
        end;

        base_utility.remove_interval("progress_node_tips_area.on_show_tips_first_end", 
                                            tonumber(progress_node_tips_area.hinting_game_id_));
        base_utility.add_interval("progress_node_tips_area.on_show_tips_first_end", 
                                            1 * 1000, tonumber(game_id));
        progress_node_tips_area.hinting_count_ = 0;
        progress_node_tips_area.hinting_game_id_ = game_id;
        progress_node_tips_area.show_all_node_tips(true);
    end;

    on_show_tips_first_end = function(user_data)
        if nil == user_data then
            return;
        end

        if progress_node_tips_area.game_id_ == tonumber(user_data) then
            if progress_node_tips_area.hinting_count_ < 10 then
                for key, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
                    if nil ~= item then
                        item:refresh_tips_positon();
                    end
                end;
                progress_node_tips_area.hinting_count_ = progress_node_tips_area.hinting_count_ + 1;
                return;
            end;
        end;

        base_utility.remove_interval("progress_node_tips_area.hide_all_node_tips", 
                                                                        tonumber(user_data));
        if progress_node_tips_area.game_id_ == tonumber(user_data) then
            progress_node_tips_area.hinting_count_ = 0;
            progress_node_tips_area.hinting_game_id_ = 0;
            progress_node_tips_area.show_all_node_tips(false);
        end;
    end;

    show_all_node_tips = function(show)
        for key, item in pairs(progress_node_tips_area.ctrl_id_to_item_) do
            if nil ~= item then
                item:show_tips(show);
            end
        end
    end;
};
